
/**
 * @file TEST_Muti_MB.c
 * @author Linquan 
 * @brief 
 * @version 0.1
 * @date 2025-07-08
 * 
 * @copyright Copyright (c) 2025
 * 
 * 用于多modbus slave口通信的Modbus解析框架。
 * 支持不同通信口，不同点表内容的解析处理。
 * 可用于 裸机、操作系统使用。
 * 这里演示裸机的使用方法。
 * 
 * 有关操作系统使用举例见： middle/serve/Muti_MB/excample.c
 * 
 */
#include "app_config.h"
#if TEST_MUTI_MB

#include "../middle/serve/Muti_MB/Muti_MB_config.h"


/* MB解析回调函数声明 
    目前支持 功能码 03 06 16 02(暫未添加)
*/
eMUTI_MB_ErrorCode ETH1_MB_handle(uint8_t function_code, uint8_t * pucRegBuffer,\
                                    uint16_t Address, uint16_t Reg_num, eMUTI_MB_RegisterMode wr_Mode);
/* MB发送函数声明 */
void ETH1_send(uint8_t* fram_ptr, uint16_t len);



/* 1、创建MB对象，一个对象对应一个串口或网口 */
MUTI_MB_object_t ETH1_MB_Object;


void task_Muti_MB_excample(void *ptr) 
{
    /* 接收到的数据包 */
    uint8_t data_recv_fun_03[] = {0,0,0,0,0,06, 00,03, 00,00, 00, 8};

    uint8_t data_recv_fun_06[] = {0,0,0,0,0,06, 00,06, 00,00, 00, 02};

    uint8_t data_recv_fun_02[] = {0,0,0,0,0,06, 00,02, 00,00, 00, 8};


    /* 2、对MB对象进行初始化，
        设置 该从站的地址，TCP协议的地址默认为0，使用 宏：MUTI_MB_TCP
            RTU协议的 根据设置需要使用 宏：MUTI_MB_RTU_X
        注册解析函数以及发送函数
    */
	MUTI_MB_object_init(&ETH1_MB_Object, MUTI_MB_TCP, &ETH1_MB_handle, &ETH1_send);


    /* 3、 将接受到的一包数据填入MB对象的接收缓冲区,
            * 从网口接收到的数据直接填充进来即可
            * 从串口接收到的数据在定时器超时后，即可填充进来，该解析框架内部会进行CRC校验检查
        向缓冲区填充，需要完成MB对象的初始化
        在填充成功后，对接收的报文进行解析处理
    */

    printf("FUNC 03:\r\n");
    if(MUTI_MB_data_append(&ETH1_MB_Object, data_recv_fun_03, sizeof(data_recv_fun_03)))
    {
        MUTI_MB_poll(&ETH1_MB_Object);
    }

    printf("FUNC 06:\r\n");
    if(MUTI_MB_data_append(&ETH1_MB_Object, data_recv_fun_06, sizeof(data_recv_fun_06)))
    {
        MUTI_MB_poll(&ETH1_MB_Object);
    }

    printf("FUNC 02:\r\n");
    if(MUTI_MB_data_append(&ETH1_MB_Object, data_recv_fun_02, sizeof(data_recv_fun_02)))
    {
        MUTI_MB_poll(&ETH1_MB_Object);
    }
}

EXPORT_Lv6_APP_SINGLE(task_Muti_MB_excample,NULL);








/*********************
ETH1 mb协议处理 
*******************/
#define ETH1_REG_HOLDING_START	0
#define ETH1_REG_HOLDING_NREGS	8
uint16_t ETH1_RegHoldingBuf[ETH1_REG_HOLDING_NREGS] = {0x1000,0x1001,0x1002,0x1003,0x1004,0x1005,0x1006,0x1007};



#define ETH1_REG_DISINPUT_START	0
#define ETH1_REG_DISINPUT_NREGS	8
uint16_t ETH1_RegDisInputBuf[ETH1_REG_DISINPUT_NREGS] = {1,1,1,1,1,1,1,1};



eMUTI_MB_ErrorCode ETH1_MB_handle(uint8_t function_code, uint8_t * pucRegBuffer,\
                            uint16_t Address, uint16_t Reg_num, eMUTI_MB_RegisterMode wr_Mode)
{
	 eMUTI_MB_ErrorCode    eStatus = MUTI_MB_ENOERR;
	 int             iRegIndex = 0;

	//printf("ETH1 function_code[%d] Address %X Reg_num %d \r\n", function_code, Address, Reg_num);	
	
	switch(function_code)
	{
		case MUTI_MB_FUNC_READ_HOLDING_REGISTER: //03
			
			// 判断地址范围 不满足范围 返回错误
		if((Address >= ETH1_REG_HOLDING_START)&&\
			((Address+Reg_num) <= (ETH1_REG_HOLDING_START + ETH1_REG_HOLDING_NREGS)))
		{
			iRegIndex = Address - 0;
		
			while(Reg_num > 0)
			{
				*pucRegBuffer++ = ( UCHAR )( ETH1_RegHoldingBuf[iRegIndex] >> 8 );
				*pucRegBuffer++ = ( UCHAR )( ETH1_RegHoldingBuf[iRegIndex] & 0xFF );
				
				//printf("read ETH1_RegHoldingBuf[%d] %x \r\n", iRegIndex, ETH1_RegHoldingBuf[iRegIndex]);

				
				iRegIndex++;
				Reg_num--;
			}
		}
		else
		{
			eStatus = MUTI_MB_ENOREG;
		}
		break;
			
		case MUTI_MB_FUNC_WRITE_REGISTER:           // 06
		case MUTI_MB_FUNC_WRITE_MULTIPLE_REGISTERS: // 16
			
		if((Address >= ETH1_REG_HOLDING_START)&&\
			((Address+Reg_num) <= (ETH1_REG_HOLDING_START + ETH1_REG_HOLDING_NREGS)))
		{
			iRegIndex = Address - 0;
		
			while(Reg_num > 0)
			{				 	
				ETH1_RegHoldingBuf[iRegIndex]  = *pucRegBuffer++ << 8;				
				ETH1_RegHoldingBuf[iRegIndex] |= *pucRegBuffer++; 
				
				printf("write ETH1_RegHoldingBuf[%d] %x \r\n",iRegIndex, ETH1_RegHoldingBuf[iRegIndex]);

				
				
				iRegIndex++;
				Reg_num--;
			}
		}
		else
		{
			eStatus = MUTI_MB_ENOREG;
		}
		
		break;

        case MUTI_MB_FUNC_READ_DISCRETE_INPUTS:     // 02

        
        break;
	
		case MUTI_MB_FUNC_READWRITE_MULTIPLE_REGISTERS://读写多个 23
		{
			switch(wr_Mode)
			{
				case MB_REG_READ:
				{
					if((Address >= ETH1_REG_HOLDING_START)&&\
						((Address+Reg_num) <= (ETH1_REG_HOLDING_START + ETH1_REG_HOLDING_NREGS)))
					{
						iRegIndex = Address - 0;
					
						while(Reg_num > 0)
						{
							*pucRegBuffer++ = ( UCHAR )( ETH1_RegHoldingBuf[iRegIndex] >> 8 );
							*pucRegBuffer++ = ( UCHAR )( ETH1_RegHoldingBuf[iRegIndex] & 0xFF );
							
							printf("read ETH1_RegHoldingBuf[%d] %x \r\n", iRegIndex, ETH1_RegHoldingBuf[iRegIndex]);
						
							iRegIndex++;
							Reg_num--;
						}
					}
					else
					{
						eStatus = MUTI_MB_ENOREG;
					}		
				}			
				break;
				
				case MB_REG_WRITE:
				{
					if((Address >= ETH1_REG_HOLDING_START)&&\
						((Address+Reg_num) <= (ETH1_REG_HOLDING_START + ETH1_REG_HOLDING_NREGS)))
					{
						iRegIndex = Address - 0;
					
						while(Reg_num > 0)
						{				 	
							ETH1_RegHoldingBuf[iRegIndex]  = *pucRegBuffer++ << 8;				
							ETH1_RegHoldingBuf[iRegIndex] |= *pucRegBuffer++; 
							
							printf("write ETH1_RegHoldingBuf[%d] %x \r\n",iRegIndex, ETH1_RegHoldingBuf[iRegIndex]);
						
							iRegIndex++;
							Reg_num--;
						}
					}
					else
					{
						eStatus = MUTI_MB_ENOREG;
					}		
				}
				break;			
			}		
		}

		break;			
	}
	return eStatus;
}




/***************************
	MB 发送回调函数
***************************/
void ETH1_send(uint8_t* fram_ptr, uint16_t len)
{  
    int i = 0;  
    
    printf("ETH1 reply: ");
    while(len--)  
    {
        printf("%#x,", fram_ptr[i]);
        i++;
    }   
    printf("\r\n");
   
}





#endif



